using System;
using System.Collections.Generic;
using System.Linq;
using Dapper;
using Dapper.Contrib.Extensions;
using Read.Models;
using Read.Utility;

namespace Read.Services
{
    public class NodeService : BaseService
    {
        protected List<NodeModel> nodelist;
        public List<NodeModel> getNodeList(int roleId)
        {
            using (var connection = GetConnection())
            {
                var access = new List<NodeModel>();

                if (roleId == 1)
                {
                    string sql = $"SELECT * FROM `{Tables.Node}` ORDER BY `Pid`";
                    access = connection.Query<NodeModel>(sql).ToList();
                }
                else
                {
                    string sql = $"SELECT * FROM `{Tables.Access}` WHERE RoleId = @RoleId";
                    string sqlnodelist = $"SELECT * FROM `{Tables.Node}` WHERE Status = 1";
                    var accessTmp = connection.Query<AccessModel>(sql, new { RoleId = roleId });
                    var nodelistTmp = connection.Query<NodeModel>(sqlnodelist).ToList();
                    access = new List<NodeModel>();
                    foreach (var itme in nodelistTmp)
                    {
                        if (accessTmp.Where(o => o.NodeId == itme.Id).Count() < 1)
                        {
                            itme.Remark = "false";
                            access.Add(itme);
                        }
                        else
                        {
                            itme.Remark = "true";
                            access.Add(itme);
                        }
                    }
                }
                return access;
            }
        }

        /// <summary>
        /// 获取权限树授权
        /// 借用Remark字段来存放是否有权
        /// </summary>
        /// <returns></returns>
        private List<NodeModel> getAccessTree(int roleId)
        {
            using (var connection = GetConnection())
            {
                string sql = $"SELECT * FROM `{Tables.Access}` WHERE RoleId = @RoleId";
                string sqlnodelist = $"SELECT * FROM `{Tables.Node}` WHERE Status = 1";
                var accessTmp = connection.Query<AccessModel>(sql, new { RoleId = roleId });
                var nodelistTmp = connection.Query<NodeModel>(sqlnodelist).ToList();
                var nodelist = new List<NodeModel>();
                foreach (var itme in nodelistTmp)
                {
                    if (roleId == 1)
                    {
                        itme.Remark = "true";
                        nodelist.Add(itme);
                    }
                    else
                    {
                        if (accessTmp.Where(o => o.NodeId == itme.Id).Count() < 1)
                        {
                            itme.Remark = "false";
                            nodelist.Add(itme);
                        }
                        else
                        {
                            itme.Remark = "true";
                            nodelist.Add(itme);
                        }
                    }
                }
                return nodelist;
            }
        }

        /// <summary>
        /// 获取菜单
        /// </summary>
        /// <param name="roleId"></param>
        /// <param name="type">区分菜单类型</param>
        /// <returns></returns>
        public ResultMenuModel getMenu(int roleId, bool type = true)
        {
            using (var connection = GetConnection())
            {
                string wheretype = type == true ? "AND Type = 1" : "";
                if (roleId == 1)
                {
                    string sql = $"SELECT * FROM `{Tables.Node}` WHERE 1=1 {wheretype} ORDER BY `Id`";
                    nodelist = connection.Query<NodeModel>(sql).ToList();
                }
                else
                {
                    string sql = $"SELECT N.* FROM `{Tables.Node}` AS N LEFT JOIN `{Tables.Access}` AS A ON A.NodeId = N.Id  WHERE RoleId = @RoleId {wheretype} ORDER BY `Id`";
                    //Console.WriteLine(sql);
                    nodelist = connection.Query<NodeModel>(sql, new { RoleId = roleId }).ToList();
                }
                return category(new ResultMenuModel(), 1);
            }
        }

        /// <summary>
        /// 获取菜单树
        /// </summary>
        /// <param name="roleId"></param>
        /// <param name="type">区分菜单类型</param>
        /// <returns></returns>
        public ResultMenuTreeModel getMenuTree(int roleId, bool type = true)
        {
            string wheretype = type == true ? "AND Type = 1" : "";
            if (roleId == 1)
            {
                //string sql = $"SELECT * FROM `{Tables.Node}` WHERE 1=1 {wheretype} ORDER BY `Level`";
                //nodelist = connection.Query<NodeModel>(sql).ToList();
                nodelist = getAccessTree(roleId);
            }
            else
            {
                //string sql = $"SELECT N.* FROM `{Tables.Node}` AS N LEFT JOIN `{Tables.Access}` AS A ON A.NodeId = N.id  WHERE RoleId = @RoleId {wheretype} AND N.Pid <> 0 ORDER BY `Level`";
                //nodelist = connection.Query<NodeModel>(sql, new { RoleId = roleId }).ToList();
                nodelist = getAccessTree(roleId);
            }
            return categorytree(new ResultMenuTreeModel(), 1);
        }

        /// <summary>
        /// 根据Id查询
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ResultNodeModel getNodeById(int id)
        {
            using (var connection = GetConnection())
            {
                var sql = $"SELECT *,(SELECT Title FROM `{Tables.Node}` AS CN WHERE N.Pid = CN.Id) AS PidName FROM `{Tables.Node}` AS N WHERE Id = @Id";
                var node = connection.QueryFirst<ResultNodeModel>(sql, new { Id = id });
                return node;
            }
        }

        /// <summary>
        /// 节点添加
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public long nodeAdd(NodeModel model)
        {
            using (var connection = GetConnection())
            {
                if (string.IsNullOrEmpty(model.Title))
                {
                    return 1;
                }
                NodeModel node = getNodeById(model.Pid);
                model.Level = node.Level + 1;
                model.Parameter = "";
                model.Status = 1;
                model.UpdateTime = Tools.ToUnixTime();
                return connection.Insert(model);
            }
        }

        /// <summary>
        /// 节点编辑
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool nodeEdit(NodeModel model)
        {
            using (var connection = GetConnection())
            {
                NodeModel node = getNodeById(model.Id);
                //Console.WriteLine("++++++++++++++++++" + model.ToJson());
                model.Level = node.Level;
                model.Parameter = node.Parameter;
                model.Status = node.Status;
                model.UpdateTime = Tools.ToUnixTime();
                //   `Id` smallint(6) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Id',
                //   `Pid` smallint(6) unsigned NOT NULL DEFAULT '0' COMMENT '上级菜单',
                //   `Level` smallint(6) NOT NULL DEFAULT '0' COMMENT '后台菜单的层级',
                //   `Icon` varchar(50) NOT NULL COMMENT '方法',
                //   `Title` varchar(50) NOT NULL COMMENT '菜单名称',
                //   `App` varchar(50) NOT NULL COMMENT '应用标识',
                //   `Controller` varchar(50) NOT NULL COMMENT '控制器',
                //   `Action` varchar(50) NOT NULL COMMENT '方法',
                //   `Parameter` varchar(255) NOT NULL COMMENT '附加参数',
                //   `Type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '类型',
                //   `Status` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否禁用',
                //   `Remark` varchar(255) NOT NULL COMMENT '备注',
                //   `Sort` smallint(6) unsigned NOT NULL DEFAULT '0' COMMENT '排序ID',
                //   `UpdateTime` int(10) NOT NULL COMMENT '更新时间',
                return connection.Update(model);
            }
        }

        /// <summary>
        /// 节点删除
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public bool nodeDel(int id)
        {
            using (var connection = GetConnection())
            {
                //NodeModel node = getNodeById(id);
                //return connection.Delete(node);
                return connection.Delete(new NodeModel() { Id = id });
            }
        }

        /// <summary>
        /// 处理菜单
        /// </summary>
        /// <param name="menu"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        private ResultMenuModel category(ResultMenuModel menu, int id)
        {
            ResultMenuModel mm = new ResultMenuModel();
            List<NodeModel> node = nodelist.Where(x => x.Pid == id).ToList();
            for (int i = 0; i < node.Count; i++)
            {
                ResultMenuModel mml = new ResultMenuModel();
                mml.id = node[i].Id;
                mml.title = node[i].Title;
                mml.icon = node[i].Icon;
                mml.url = $"/{node[i].App}/{node[i].Controller}/{node[i].Action}";
                mml.spread = true;
                category(mml, node[i].Id);
                if (id == 1)// id = 0 是根节点
                {
                    NodeModel nodeTmp = nodelist.Where(x => x.Id == id).ToList()[0];
                    mm.id = nodeTmp.Id;
                    mm.title = nodeTmp.Title;
                    mm.icon = nodeTmp.Icon;
                    mm.url = "";
                    mm.spread = true;
                    mm.children.Add(mml);
                }
                menu.children.Add(mml);
            }
            return mm;
        }

        /// <summary>
        /// 处理菜单树
        /// </summary>
        /// <param name="menu"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        private ResultMenuTreeModel categorytree(ResultMenuTreeModel menu, int id)
        {
            ResultMenuTreeModel mm = new ResultMenuTreeModel();
            List<NodeModel> node = nodelist.Where(x => x.Pid == id).ToList();
            for (int i = 0; i < node.Count; i++)
            {
                ResultMenuTreeModel mml = new ResultMenuTreeModel();
                mml.id = node[i].Id;
                mml.name = node[i].Title;
                mml.open = true;
                mml.isParent = false;
                mml.@checked = node[i].Remark == "true" ? true : false;
                categorytree(mml, node[i].Id);
                if (id == 1)// id = 0 是根节点
                {
                    NodeModel nodeTmp = nodelist.Where(x => x.Id == id).ToList()[0];
                    mm.id = nodeTmp.Id;
                    mm.name = nodeTmp.Title;
                    mm.open = true;
                    mm.isParent = false;
                    mm.@checked = nodeTmp.Remark == "true" ? true : false;
                    mm.children.Add(mml);
                }
                menu.children.Add(mml);
            }
            return mm;
        }
    }
}